package com.ch04.ex46;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;

/**
 * Created by zc on 2016/2/19.
 */
public class DocumentTask extends RecursiveTask<Integer> {
    private String document[][];
    private int start, end;
    private String word;

    public DocumentTask(String[][] document,
                        int start,
                        int end,
                        String word) {
        this.document = document;
        this.start = start;
        this.end = end;
        this.word = word;
    }

    @Override
    protected Integer compute() {
        Integer result = 0;
        if(end-start<10){
            result = processLines(document, start, end, word);
        } else {
            int mid = (start+end)/2;
            DocumentTask task1 = new DocumentTask(document,start,mid, word);
            DocumentTask task2 = new DocumentTask(document,mid, end, word);
            invokeAll(task1, task2);

            try {
                result = groupResults(task1.get(), task2.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private Integer groupResults(Integer number1, Integer number2) {

        return number1 + number2;
    }

    private Integer processLines(String[][] document,
                             int start,
                             int end,
                             String word) {
        List<LineTask> tasks = new ArrayList<>();
        for(int i=start; i<end; i++){
            LineTask task = new LineTask(document[i],start,end,word);
            tasks.add(task);
        }

        invokeAll(tasks);

        int result = 0;
        for(int i=0; i<tasks.size(); i++){
            LineTask task = tasks.get(i);
            try {
                result += task.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}
